package com.heima.media.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.minio.MinIOService;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.media.dto.ArticleDto;
import com.heima.media.dto.ContentDto;
import com.heima.media.dto.ImageDto;
import com.heima.media.entity.WmChannel;
import com.heima.media.entity.WmNews;
import com.heima.media.entity.WmSensitive;
import com.heima.media.entity.WmUser;
import com.heima.media.feign.ArticleFeign;
import com.heima.media.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class AuditServiceImpl implements IAuditService {

    @Autowired
    private GreenTextScan greenTextScan;

    @Autowired
    private GreenImageScan greenImageScan;

    @Autowired
    @Lazy
    private IWmNewsService wmNewsService;

    @Autowired
    private MinIOService minIOService;

    @Autowired
    private ArticleFeign articleFeign;

    @Autowired
    private IWmUserService wmUserService;

    @Autowired
    private IWmChannelService wmChannelService;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    @Async
    public void audit(WmNews wmNews) {
        boolean isPass = true;

        //自管理敏感词审核
        isPass = checkSensitive(wmNews);
        if (!isPass) return;

        //审核自媒体文章的文本内容
        isPass = checkText(wmNews);
        if (!isPass) return;

        //审核自媒体文章的图片内容
        isPass = checkImage(wmNews);
        if (!isPass) return;

        //审核通过  feign远程调用  保存apArticle
        //判断是否已将到发布时间  当前时间 > 发布时间
        if (System.currentTimeMillis() >= wmNews.getPublishTime().getTime()) {
            //feign调用  保存APArticle
            Long articleId = saveApArticle(wmNews);
            wmNews.setArticleId(articleId);

            wmNews.setStatus(9);
            wmNewsService.updateById(wmNews);

        } else {
            //修改状态
            wmNews.setStatus(8);
            wmNewsService.updateById(wmNews);

            //使用redisson做延时任务
            RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque("news-dqueue");
            //获取延时队列
            RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
            //放入数据
            Long time = wmNews.getPublishTime().getTime() - System.currentTimeMillis();
            delayedQueue.offer(wmNews.getId(), time, TimeUnit.MILLISECONDS);
            log.info("延时消息发送成功，预计在 " + time + "毫秒后，执行" + new Date());
        }

    }

    @Autowired
    private IWmSensitiveService wmSensitiveService;

    private boolean checkSensitive(WmNews wmNews) {
        //初始化DFA算法的Map
        List<WmSensitive> wmSensitiveList = wmSensitiveService.list();

        //List<String> stringList = wmSensitiveList.stream().map(s -> s.getSensitives()).collect(Collectors.toList());
        List<String> stringList = new ArrayList<>();
        for (WmSensitive wmSensitive : wmSensitiveList) {
            stringList.add(wmSensitive.getSensitives());
        }
        SensitiveWordUtil.initMap(stringList);

        //检查文章文本是否包含敏感词
        String text = wmNews.getTitle();
        //审核文章标题，文章内容
        String content = wmNews.getContent();
        List<ContentDto> contentDtos = JSON.parseArray(content, ContentDto.class);

        for (ContentDto contentDto : contentDtos) {
            if (contentDto.getType().equals("text")) {
                text += contentDto.getValue();
            }
        }

        Map<String, Integer> matchWordsMap = SensitiveWordUtil.matchWords(text);
        if (matchWordsMap.size() == 0) {
            return true;
        } else {
            wmNews.setStatus(2);
            Set<String> strings = matchWordsMap.keySet();
            String reason = String.join(",", strings);
            wmNews.setReason("阿里云敏感词审核失败，原因是内容包含：" + reason);
            wmNewsService.updateById(wmNews);
            return false;
        }
    }

    @Override
    public void audit(Integer newsId) {
        WmNews wmNews = wmNewsService.getById(newsId);
        audit(wmNews);
    }

    //远程发布app文章
    public Long saveApArticle(WmNews wmNews) {
        ArticleDto dto = new ArticleDto();
        dto.setContent(wmNews.getContent());//文章内容
//        articleDto.setId();
        dto.setTitle(wmNews.getTitle());//标题

        WmUser wmUser = wmUserService.getById(wmNews.getUserId());
        dto.setAuthorId(wmUser.getApAuthorId());//文章作者的ID
        dto.setAuthorName(wmUser.getName());//作者昵称
        dto.setChannelId(wmNews.getChannelId());//文章所属频道ID

        WmChannel wmChannel = wmChannelService.getById(wmNews.getChannelId());
        dto.setChannelName(wmChannel.getName());//频道名称
        dto.setLayout(wmNews.getType());//文章布局    0 无图文章    1 单图文章            2 多图文章
        dto.setFlag(0);//文章标记    0 普通文章    1 热点文章

        String images = wmNews.getImages();
        List<ImageDto> imageDtoList = JSON.parseArray(images, ImageDto.class);

        List<String> urlList = new ArrayList<>();
        for (ImageDto imageDto : imageDtoList) {
            urlList.add(imageDto.getUrl());
        }

        dto.setImages(String.join(",", urlList));//文章图片   多张逗号分隔
        dto.setLabels(wmNews.getLabels());
        dto.setPublishTime(wmNews.getPublishTime());//发布时间

        return articleFeign.saveApArticle(dto).getData();
    }


    //审核自媒体文章的图片内容
    private boolean checkImage(WmNews wmNews) {
        List<ImageDto> imageDtoList = JSON.parseArray(wmNews.getImages(), ImageDto.class);


        //审核文章封面图片，文章内容图片
        String content = wmNews.getContent();
        List<ContentDto> contentDtos = JSON.parseArray(content, ContentDto.class);

        for (ContentDto contentDto : contentDtos) {
            if (contentDto.getType().equals("image")) {
                ImageDto imageDto = new ImageDto();
                imageDto.setId(contentDto.getId());
                imageDto.setUrl(contentDto.getValue());

                if (imageDtoList.contains(imageDto)) {
                    imageDtoList.add(imageDto);
                }
            }
        }

        //imageDtoList已有封面和内容的图片

        try {
            List<byte[]> imageList = new ArrayList<>();
            //图片下载，下载后上传到阿里云审核
            for (ImageDto imageDto : imageDtoList) {
                InputStream inputStream = minIOService.download(imageDto.getUrl());
                byte[] bytes = IOUtils.toByteArray(inputStream);
                imageList.add(bytes);
            }

            Map map = greenImageScan.imageScan(imageList);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion) {
                case "pass": {
                    return true;
                }
                case "review": {
                    //修改自媒体文章的状态和原因
                    wmNews.setStatus(3);
                    String lable = (String) map.get("lable");
                    wmNews.setReason("阿里云图片审核失败需人工介入，原因是：" + lable);
                    wmNewsService.updateById(wmNews);
                    return false;
                }
                case "block": {
                    wmNews.setStatus(2);
                    String lable = (String) map.get("lable");
                    wmNews.setReason("阿里云图片审核失败，原因是：" + lable);
                    wmNewsService.updateById(wmNews);
                    return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;

    }


    //审核自媒体文章的文本内容
    private boolean checkText(WmNews wmNews) {
        String text = wmNews.getTitle();

        //审核文章标题，文章内容
        String content = wmNews.getContent();
        List<ContentDto> contentDtos = JSON.parseArray(content, ContentDto.class);

        for (ContentDto contentDto : contentDtos) {
            if (contentDto.getType().equals("text")) {
                text += contentDto.getValue();
            }
        }

        try {
            Map map = greenTextScan.greenTextScan(text);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion) {
                case "pass": {
                    return true;
                }
                case "review": {
                    //修改自媒体文章的状态和原因
                    wmNews.setStatus(3);
                    String lable = (String) map.get("lable");
                    wmNews.setReason("阿里云文本审核失败需人工介入，原因是：" + lable);
                    wmNewsService.updateById(wmNews);
                    return false;
                }
                case "block": {
                    wmNews.setStatus(2);
                    String lable = (String) map.get("lable");
                    wmNews.setReason("阿里云文本审核失败，原因是：" + lable);
                    wmNewsService.updateById(wmNews);
                    return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


}
